package cn.zhaozhiqi.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.zhaozhiqi.constants.Constants;
import cn.zhaozhiqi.constants.ErrorCode;
import cn.zhaozhiqi.mapper.DriverAuthMaterialMapper;
import cn.zhaozhiqi.pojo.domain.Driver;
import cn.zhaozhiqi.pojo.domain.DriverAuthMaterial;
import cn.zhaozhiqi.pojo.dto.AppDriverAuthMaterialDto;
import cn.zhaozhiqi.pojo.dto.JudgeAuthDto;
import cn.zhaozhiqi.service.IDriverAuthMaterialService;
import cn.zhaozhiqi.service.IDriverService;
import cn.zhaozhiqi.utils.AssertUtil;
import cn.zhaozhiqi.utils.BitStatesUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.Date;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


/**
 * <p>
 * 司机实名资料 服务实现类
 * </p>
 *
 * @author zhaozhiqi
 * @since 2024-12-17
 */
@Service
public class DriverAuthMaterialServiceImpl extends ServiceImpl<DriverAuthMaterialMapper, DriverAuthMaterial> implements IDriverAuthMaterialService {

    @Autowired
    private IDriverService driverService;
    @Override
    public Boolean saveDriveAuthMaterial(AppDriverAuthMaterialDto dto) {
        /*
        1.需要进行合法性校验，即电话是否错误，身份证是否错误，等
        2.进行真实性校验，即姓名和身份证号是否一致？这个需要插件   //TODO
        3.业务校验：即司机的审核状态是审核中或者已审核，就不能继续添加了
        4.保存信息，保存司机校验表，保存司机表中的位状态
        5.返回
         */
        AssertUtil.isPhone(dto.getPhone(), ErrorCode.PARAM_PHONE_ERROR);
        //业务校验  1.拿到司机登录id查询是否存在认证资料；
        Date date = new Date();
        long loginId = StpUtil.getLoginIdAsLong();
        //拿到司机登录的id后在DriverAuthMaterial表中按照id和状态查询是否存在对象,
        LambdaQueryWrapper<DriverAuthMaterial> wrapper = new LambdaQueryWrapper<DriverAuthMaterial>()
                .eq(DriverAuthMaterial::getDriverId,loginId)
                .in(DriverAuthMaterial::getRealAuthStatus, Constants.AuthStatus.WATTING,Constants.AuthStatus.PASS);
        //如果没有审核中和通过两种状态的数据，就继续，进行数据的新增或覆盖
        AssertUtil.isNull(super.getOne(wrapper),ErrorCode.SUBMIT_AUTH_REAPT);
        //如果之前没有记录，就进行数据的添加
        DriverAuthMaterial driverAuthMaterial = new DriverAuthMaterial();
        //拷贝属性
        BeanUtils.copyProperties(dto,driverAuthMaterial);
        //设置对象内的其他属性
        driverAuthMaterial.setRealAuthStatus(Constants.AuthStatus.WATTING);
        driverAuthMaterial.setCreateTime(date);
        driverAuthMaterial.setDeleted(false);
        driverAuthMaterial.setDriverId(loginId);
        super.save(driverAuthMaterial);
        //同时更改司机表中的位状态
        Driver driver = driverService.getById(loginId);
        driver.setBitState(BitStatesUtils.addState(driver.getBitState(),BitStatesUtils.OP_REAL_AUTHENTICATING));
        driverService.updateById(driver);
        return true;
    }

    /**
     * 根据司机的信息id获取该司机的认证信息
     * @return
     */
    @Override
    public DriverAuthMaterial getAuthByDriverId() {
        long loginId = StpUtil.getLoginIdAsLong();
        LambdaQueryWrapper<DriverAuthMaterial> wrapper = new LambdaQueryWrapper<DriverAuthMaterial>()
                .eq(DriverAuthMaterial::getDriverId,loginId);
        return super.getOne(wrapper);
    }

    /**
     * 判断是否通过认证的方法
     * 1.审核通过   修改认证信息状态  司机位状态
     * 2.审核不通过  修改认证信息状态  司机位状态
     * @param dto
     * @return
     */
    @Override
    public Boolean judgeAuth(JudgeAuthDto dto) {
        //拿到待认证信息，判断当前状态是否是认证中；只有这两种才可以继续审核
        DriverAuthMaterial material = super.getById(dto.getId());
        //断言是否是认证中的状态，否则报错不能审核
        AssertUtil.isEquals(material.getRealAuthStatus(),Constants.AuthStatus.WATTING,ErrorCode.AUTH_STATUS_ERROR);
        //拿到判断信息修改认证状态
        Driver driver = driverService.getById(material.getDriverId());
        //先移除司机的认证中位状态
        Driver driverRemove = driver.setBitState(BitStatesUtils
                .removeState(driver.getBitState(), BitStatesUtils.OP_REAL_AUTHENTICATING));
        material.setAuditRemark(dto.getRemark());
        //根据认证是否通过修改位状态
        if (dto.getApprove()){
            //增加认证成功的位状态
            driverRemove.setBitState(BitStatesUtils
                    .addState(driverRemove.getBitState(),BitStatesUtils.OP_REAL_AUTHENTICATIONED));
            //修改认证信息
            material.setRealAuthStatus(Constants.AuthStatus.PASS);
        }else {
            //修改认证信息
            material.setRealAuthStatus(Constants.AuthStatus.REJECT);
        }
        super.updateById(material);
        driverService.updateById(driverRemove);
        return true;
    }
}
